#include "authmanager.h"
#include <QRandomGenerator>

AuthManager* AuthManager::instance = nullptr;

AuthManager* AuthManager::getInstance()
{
    if (instance == nullptr) {
        instance = new AuthManager();
    }
    return instance;
}

AuthManager::AuthManager(QObject *parent) : QObject(parent)
{
    // 创建一个默认的管理员账户
    if (!userExists("admin")) {
        registerUser("admin", "ok", UserRole::Admin);
        LOG_INFO("创建默认管理员账户: admin/ok");
    }
}

AuthManager::~AuthManager()
{
}

bool AuthManager::registerUser(const QString &username, const QString &password, UserRole role)
{
    if (username.isEmpty() || password.isEmpty()) {
        LOG_WARNING("用户注册失败: 用户名或密码为空");
        return false;
    }
    
    if (userExists(username)) {
        LOG_WARNING(QString("用户注册失败: 用户名'%1'已存在").arg(username));
        return false;
    }
    
    QString salt = generateSalt();
    QString passwordHash = hashPassword(password, salt);
    
    UserInfo newUser;
    newUser.username = username;
    newUser.passwordHash = passwordHash;
    newUser.salt = salt;
    newUser.role = role;
    newUser.lastLoginTime = "";
    newUser.lastLoginIP = "";
    
    users.insert(username, newUser);
    LOG_INFO(QString("用户'%1'注册成功，角色: %2").arg(username).arg(roleToString(role)));
    
    return true;
}

bool AuthManager::authenticateUser(const QString &username, const QString &password)
{
    if (!userExists(username)) {
        LOG_WARNING(QString("认证失败: 用户'%1'不存在").arg(username));
        emit loginFailed("用户不存在");
        return false;
    }
    
    UserInfo user = users.value(username);
    QString hashedPassword = hashPassword(password, user.salt);
    
    if (hashedPassword != user.passwordHash) {
        LOG_WARNING(QString("认证失败: 用户'%1'密码错误").arg(username));
        emit loginFailed("密码错误");
        return false;
    }
    
    // 更新登录信息
    user.lastLoginTime = QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss");
    // 这里应该设置实际的IP地址，但为简单起见，使用了一个固定值
    user.lastLoginIP = "127.0.0.1";
    users[username] = user;
    
    // 设置当前登录用户
    currentUser = username;
    
    LOG_INFO(QString("用户'%1'认证成功").arg(username));
    emit loginSuccess(username, user.role);
    
    return true;
}

bool AuthManager::changePassword(const QString &username, const QString &oldPassword, const QString &newPassword)
{
    if (!userExists(username)) {
        LOG_WARNING(QString("修改密码失败: 用户'%1'不存在").arg(username));
        return false;
    }
    
    UserInfo user = users.value(username);
    QString hashedOldPassword = hashPassword(oldPassword, user.salt);
    
    if (hashedOldPassword != user.passwordHash) {
        LOG_WARNING(QString("修改密码失败: 用户'%1'旧密码错误").arg(username));
        return false;
    }
    
    // 生成新的盐值和密码哈希
    QString newSalt = generateSalt();
    QString newPasswordHash = hashPassword(newPassword, newSalt);
    
    user.passwordHash = newPasswordHash;
    user.salt = newSalt;
    users[username] = user;
    
    LOG_INFO(QString("用户'%1'密码修改成功").arg(username));
    
    return true;
}

UserInfo AuthManager::getUserInfo(const QString &username) const
{
    return users.value(username);
}

bool AuthManager::userExists(const QString &username) const
{
    return users.contains(username);
}

bool AuthManager::saveUsersToFile(const QString &filePath)
{
    QJsonArray usersArray;
    
    QHashIterator<QString, UserInfo> i(users);
    while (i.hasNext()) {
        i.next();
        UserInfo user = i.value();
        
        QJsonObject userObj;
        userObj["username"] = user.username;
        userObj["passwordHash"] = user.passwordHash;
        userObj["salt"] = user.salt;
        userObj["role"] = roleToString(user.role);
        userObj["lastLoginTime"] = user.lastLoginTime;
        userObj["lastLoginIP"] = user.lastLoginIP;
        
        usersArray.append(userObj);
    }
    
    QJsonObject rootObj;
    rootObj["users"] = usersArray;
    
    QJsonDocument doc(rootObj);
    QFile file(filePath);
    
    if (!file.open(QIODevice::WriteOnly)) {
        LOG_ERROR(QString("无法打开文件保存用户信息: %1").arg(filePath));
        return false;
    }
    
    file.write(doc.toJson());
    file.close();
    
    LOG_INFO(QString("用户信息已保存到文件: %1").arg(filePath));
    
    return true;
}

bool AuthManager::loadUsersFromFile(const QString &filePath)
{
    QFile file(filePath);
    
    if (!file.exists()) {
        LOG_WARNING(QString("用户数据文件不存在: %1").arg(filePath));
        return false;
    }
    
    if (!file.open(QIODevice::ReadOnly)) {
        LOG_ERROR(QString("无法打开文件读取用户信息: %1").arg(filePath));
        return false;
    }
    
    QByteArray data = file.readAll();
    file.close();
    
    QJsonParseError parseError;
    QJsonDocument doc = QJsonDocument::fromJson(data, &parseError);
    
    if (parseError.error != QJsonParseError::NoError) {
        LOG_ERROR(QString("JSON解析错误: %1").arg(parseError.errorString()));
        return false;
    }
    
    if (!doc.isObject() || !doc.object().contains("users")) {
        LOG_ERROR("无效的用户数据文件格式");
        return false;
    }
    
    QJsonArray usersArray = doc.object()["users"].toArray();
    users.clear();
    
    for (int i = 0; i < usersArray.size(); ++i) {
        QJsonObject userObj = usersArray[i].toObject();
        
        UserInfo user;
        user.username = userObj["username"].toString();
        user.passwordHash = userObj["passwordHash"].toString();
        user.salt = userObj["salt"].toString();
        user.role = stringToRole(userObj["role"].toString());
        user.lastLoginTime = userObj["lastLoginTime"].toString();
        user.lastLoginIP = userObj["lastLoginIP"].toString();
        
        users.insert(user.username, user);
    }
    
    LOG_INFO(QString("从文件加载了 %1 个用户").arg(users.size()));
    
    return true;
}

QString AuthManager::getCurrentUser() const
{
    return currentUser;
}

bool AuthManager::checkPermission(UserRole requiredRole) const
{
    if (currentUser.isEmpty()) {
        LOG_WARNING("权限检查失败: 没有登录的用户");
        return false;
    }
    
    UserInfo user = users.value(currentUser);
    
    // 管理员拥有所有权限
    if (user.role == UserRole::Admin) {
        return true;
    }
    
    // 检查用户角色是否满足要求
    return static_cast<int>(user.role) <= static_cast<int>(requiredRole);
}

void AuthManager::logout()
{
    if (!currentUser.isEmpty()) {
        LOG_INFO(QString("用户'%1'退出登录").arg(currentUser));
        currentUser.clear();
        emit userLogout();
    }
}

QString AuthManager::hashPassword(const QString &password, const QString &salt)
{
    QByteArray combined = password.toUtf8() + salt.toUtf8();
    QByteArray hash = QCryptographicHash::hash(combined, QCryptographicHash::Sha256);
    return hash.toHex();
}

QString AuthManager::generateSalt()
{
    const QString chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
    QString salt;
    
    for (int i = 0; i < 16; ++i) {
        int index = QRandomGenerator::global()->bounded(chars.length());
        salt.append(chars.at(index));
    }
    
    return salt;
}

QString AuthManager::roleToString(UserRole role)
{
    switch (role) {
    case UserRole::Admin:
        return "Admin";
    case UserRole::Standard:
        return "Standard";
    case UserRole::Guest:
        return "Guest";
    default:
        return "Unknown";
    }
}

UserRole AuthManager::stringToRole(const QString &roleStr)
{
    if (roleStr == "Admin") return UserRole::Admin;
    if (roleStr == "Standard") return UserRole::Standard;
    if (roleStr == "Guest") return UserRole::Guest;
    
    LOG_WARNING(QString("未知用户角色: %1，使用默认值 Guest").arg(roleStr));
    return UserRole::Guest;
}
